﻿#ifndef __DATASTREAM_FIFO_H__
#define __DATASTREAM_FIFO_H__

#include <string.h>
#include <mutex>

#include "RingBuffer.h"

namespace pi {
namespace utils {

inline int str_search(const char src[], const char str[], int n)
{
    int i, j, firstOcc;
    i = 0, j = 0;

    while ( i < n )
    {
        while ( src[i] != str[0] )
        {
            i++;
            if( i >= n ) return -1;
        }

        if ( i >= n )
            return (-1);

        firstOcc = i;

        while (src[i] == str[j] && str[j] != '\0')
        {
            i++;
            j++;

            if( i >= n ) return -1;
        }

        if (str[j] == '\0')
            return (firstOcc);
        if( i >= n )
            return -1;

        i = firstOcc + 1;
        j = 0;

        if( i >= n ) return -1;
    }
}


template <typename BufType=unsigned char>
class Datastream_FIFO : public RingBuffer<BufType>
{
public:
    Datastream_FIFO(int size=1024)
        : RingBuffer<BufType>(size)
    {
    }

    virtual ~Datastream_FIFO()
    {
    }


    virtual int find_tag(const char *tag)
    {
        int n, p;

        if( this->writeIdx > this->readIdx )
        {
            WriteMutex lock(this->mutexBuf);

            n = this->writeIdx - this->readIdx;
            p = str_search((const char*)(this->data+this->readIdx*sizeof(BufType)), tag, n);

            return p;
        }
        else
        {
            WriteMutex lock(this->mutexBuf);

            n = this->dataSize - this->readIdx;
            p = str_search((const char*)(this->data+this->readIdx*sizeof(BufType)), tag, n);
            if( p != -1 ) return p;

            n = this->writeIdx;
            p = str_search((const char*)(this->data), tag, n);

            return p;
        }
    }
};

} } // end of namespace pi::utils


#endif // __DATASTREAM_FIFO_H__
